﻿Imports System.Globalization
Imports CATALooK
Imports System.Reflection
Imports System.Linq


Namespace Aricie.DNN.Services.Url.FriendlyUrl.Providers

    Public Class CatalookUrlRewriter
        Implements IUrlRewriterProvider
        Implements IIsActive


        Private Property CATAssembly As Assembly
        Private Property CATVersion As System.Version

        Public Sub New()
            Try
                Dim objType As Type = DotNetNuke.Framework.Reflection.CreateType("CATALooK.ProductsDB, CATALooKStore", True)
                If objType IsNot Nothing Then
                    CATAssembly = objType.Assembly 'Assembly.Load("CATALooKStore")
                    CATVersion = CATAssembly.GetName.Version
                End If
            Catch
            End Try
        End Sub

        Public Function GetModuleRewrites() As List(Of GroupParamsRewrite) Implements IUrlRewriterProvider.GetRewrites
            Dim toReturn As New List(Of GroupParamsRewrite)
            Dim desc As String = "Name of the catalook product being browsed"
            toReturn.Add(New GroupParamsRewrite("ProductName", desc, RewriteType.SubPath, UrlParam.FromSyntax("ProductID")) With {.Localized = True})
            desc = "Name of the catalook category being browsed"
            toReturn.Add(New GroupParamsRewrite("CategoryName", desc, RewriteType.SubPath, UrlParam.FromSyntax("CategoryID")) With {.Localized = True})
            desc = "Name of the catalook advanced category being browsed"
            toReturn.Add(New GroupParamsRewrite("AdvCatName", desc, RewriteType.SubPath, UrlParam.FromSyntax("CategoryID")) With {.Localized = True})
            Return toReturn
        End Function

        Public Function RewriteParams(ByVal groupName As String, ByVal objRewriteType As RewriteType, _
                                       ByVal params As Dictionary(Of UrlParam, String), ByVal behaviour As FriendlierUrlStrategy) As GroupRewriteResult _
            Implements IUrlRewriterProvider.RewriteParams
            Dim toReturn As New GroupRewriteResult()

            Dim culture As String = Threading.Thread.CurrentThread.CurrentCulture.ToString()
            If (params.ContainsKey(UrlParam.Language) AndAlso Not String.IsNullOrEmpty(params(UrlParam.Language))) Then
                culture = params(UrlParam.Language)
            End If

            If params.Count > 0 Then
                Select Case groupName.ToLowerInvariant
                    Case "productname"
                        Dim productId As Integer = Integer.Parse(params(UrlParam.FromSyntax("productid")), CultureInfo.InvariantCulture)
                        toReturn.RewriteValue = Me.GetProductName(productId, culture, behaviour)
                        toReturn.ConsumedParameters(UrlParam.FromSyntax("productid")) = True
                    Case "categoryname"
                        Dim categoryId As Integer = Integer.Parse(params(UrlParam.FromSyntax("categoryid")), CultureInfo.InvariantCulture)
                        toReturn.RewriteValue = Me.GetCategoryName(categoryId, culture, behaviour)
                        toReturn.ConsumedParameters(UrlParam.FromSyntax("categoryid")) = True
                    Case "advcatname"
                        Dim categoryId As Integer = Integer.Parse(params(UrlParam.FromSyntax("categoryid")), CultureInfo.InvariantCulture)
                        toReturn.RewriteValue = Me.GetAdvCategoryName(categoryId, culture, behaviour)
                        toReturn.ConsumedParameters(UrlParam.FromSyntax("categoryid")) = True
                End Select
            End If
            Return toReturn
        End Function

        Public Function GetProductName(ByVal productId As Integer, culture As String, ByVal behaviour As FriendlierUrlStrategy) As String
            Dim controller As New ProductsDB
            Dim ctlrType As Type = controller.GetType()
            Dim getSingleProductsMethod As MethodInfo
            Dim objProductInfo As ProductInfo
            If (CATVersion.Major = 5 And CATVersion.Minor < 8) Or CATVersion.Major < 5 Then
                getSingleProductsMethod = ctlrType.GetMethod("CAT_GetSingleProducts", New Type() {GetType(Integer), GetType(Integer), GetType(Boolean), GetType(RequestType)})
                objProductInfo = getSingleProductsMethod.Invoke(controller, New Object() {productId, NukeHelper.PortalId, False, RequestType.AdminRequest})
            Else
                getSingleProductsMethod = ctlrType.GetMethod("CAT_GetSingleProducts", New Type() {GetType(Integer), GetType(Boolean), GetType(RequestType), GetType(Integer)})
                objProductInfo = getSingleProductsMethod.Invoke(controller, New Object() {productId, False, RequestType.AdminRequest, NukeHelper.PortalId})
            End If
            Dim toReturn As String = String.Empty
            If objProductInfo IsNot Nothing Then
                toReturn = GetLocalizedContent(ItemType.Product, productId, 0, objProductInfo.ProductName, PortalId, String.Empty, culture)
            Else
                Throw New ApplicationException(String.Format("Product with productid {0} not found  for url rewriting", productId.ToString(CultureInfo.InvariantCulture)))
            End If
            'Return behaviour.StringEscaper.EscapeString(toReturn)
            Return toReturn
        End Function

        Public Function GetCategoryName(ByVal categoryId As Integer, culture As String, ByVal behaviour As FriendlierUrlStrategy) As String
            Dim controller As New CategoryController
            Dim objCategoryInfo As CategoryInfo = controller.CAT_GetCategory(categoryId, NukeHelper.PortalId)
            Dim toReturn As String = String.Empty
            If objCategoryInfo IsNot Nothing Then
                toReturn = objCategoryInfo.CategoryName
            Else
                Throw New ApplicationException(String.Format("Category with categoryid {0} not found  for url rewriting", categoryId.ToString(CultureInfo.InvariantCulture)))
            End If
            'Return behaviour.StringEscaper.EscapeString(toReturn)
            Return toReturn
        End Function

        Public Function GetAdvCategoryName(ByVal categoryId As Integer, culture As String, ByVal behaviour As FriendlierUrlStrategy) As String
            Dim controller As New AdvCatController
            Dim objAdvCatInfo As AdvCatInfo = controller.GetAdvCat(categoryId)
            Dim toReturn As String = String.Empty
            If objAdvCatInfo IsNot Nothing Then
                toReturn = GetLocalizedContent(ItemType.AdvCat, categoryId, 0, objAdvCatInfo.AdvCatName, PortalId, String.Empty, culture)
            Else
                Throw New ApplicationException(String.Format("Advanced Category with categoryid {0} not found  for url rewriting", categoryId.ToString(CultureInfo.InvariantCulture)))
            End If
            'Return behaviour.StringEscaper.EscapeString(toReturn)
            Return toReturn
        End Function

        Private ReadOnly Property UseNewLocalizeContent As Boolean
            Get
                Return CATVersion.Major >= 6
            End Get
        End Property



        Private Shared LocalizeContentMethod As MethodInfo = Nothing
        Private Function GetLocalizedContent(CurrentItemType As ItemType, Id As Integer, DBField As Integer, translation As String, portalId As Integer, index As String, culture As String) As String
            Dim lcType = GetType(LocalizeContent)
            If (LocalizeContentMethod Is Nothing) Then
                LocalizeContentMethod = lcType.GetMethods().Where(Function(mi) mi.Name = "GetLocalizedContent").First()
            End If
            Dim ParamList As New List(Of Object)
            ParamList.AddRange(New Object() {CurrentItemType, Id, DBField, translation})
            If UseNewLocalizeContent Then
                ParamList.AddRange(New Object() {portalId, index, culture})
            End If

            Return LocalizeContentMethod.Invoke(Nothing, ParamList.ToArray()).ToString
        End Function

        Public ReadOnly Property IsActive As Boolean Implements IIsActive.IsActive
            Get
                Return DotNetNuke.Framework.Reflection.CreateType("CATALooK.ProductsDB, CATALooKStore", True) IsNot Nothing
            End Get
        End Property
    End Class
End Namespace


